package com.cgc.venus.server.core.k8s.impl;
import com.cgc.venus.server.core.bean.response.VenusResponseStatus;
import com.cgc.venus.server.core.exception.VenusException;
import com.cgc.venus.server.core.k8s.inter.K8sStorageService;
import com.cgc.venus.server.core.utils.StringUtil;
import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import java.util.List;

/**
 * Created by 业哥 on 2017/12/5.
 */
@Service
public class K8sStorageServiceImpl implements K8sStorageService {
    private Logger logger = LoggerFactory.getLogger(K8sStorageServiceImpl.class);
    @Autowired
    private KubernetesClient k8sClient;
    private static String STORAGE_CLASS="managed-nfs-storage";//存储类
    public static String ANNOTATION_KYE_APP="app";
    public static String ANNOTATION_KYE_MOUNT_PATH="mountPath";

    @Override
    public List<PersistentVolumeClaim> getPersistentVolumeClaims(String namespace) throws VenusException {
        PersistentVolumeClaimList persistentVolumeClaimList=null;
        //查所有ns
        if(StringUtil.isEmpty(namespace)){
            persistentVolumeClaimList=k8sClient.persistentVolumeClaims().list();
        }else{
            //查特点ns
            NonNamespaceOperation rr=k8sClient.persistentVolumeClaims().inNamespace(namespace);
            persistentVolumeClaimList= (PersistentVolumeClaimList) rr.list();
        }
        return persistentVolumeClaimList.getItems();
    }

    @Override
    public PersistentVolumeClaim getPersistentVolumeClaim(String pvcName,String namespace) throws VenusException {
        List<PersistentVolumeClaim> list=this.getPersistentVolumeClaims(namespace);
        for(PersistentVolumeClaim pvc:list){
            if(pvc.getMetadata().getName().equals(pvcName)&&pvc.getMetadata().getNamespace().equals(namespace)){
                return pvc;
            }
        }
        return null;
    }

    @Override
    public Boolean setPersistentVolumeClaim(String pvcName,String namespace,String appName,String mountPath) throws VenusException {
        try {
            PersistentVolumeClaim persistentVolumeClaim=this.getPersistentVolumeClaim(pvcName,namespace);
            Map<String,String> map=null;
            if(persistentVolumeClaim.getMetadata().getAnnotations()==null){
                map=new HashMap<String,String>();
                persistentVolumeClaim.getMetadata().setAnnotations(map);
            }else{
                map=persistentVolumeClaim.getMetadata().getAnnotations();
            }
            map.put(ANNOTATION_KYE_APP, appName);
            map.put(ANNOTATION_KYE_MOUNT_PATH,mountPath);
            k8sClient.persistentVolumeClaims().inNamespace(namespace).createOrReplace(persistentVolumeClaim);
            return true;
        }catch (KubernetesClientException ex){
            logger.error(ex.getMessage(),ex);
            throw new VenusException(VenusResponseStatus.K8S_EXCEPTION, "k8s异常,设置失败!");
        }
    }

    @Override
    public Boolean scalePersistentVolumeClaim(String pvcName, String namespace, String reqStorageSize) throws VenusException {
        PersistentVolumeClaim persistentVolumeClaim=this.getPersistentVolumeClaim(pvcName,namespace);
        Map<String,Quantity> requests=new HashMap<String,Quantity>();
        requests.put("storage",new Quantity(reqStorageSize));
        persistentVolumeClaim.getSpec().getResources().setRequests(requests);
        k8sClient.persistentVolumeClaims().createOrReplace(persistentVolumeClaim);
        return true;
    }

    @Override
    public Boolean deletePersistentVolumeClaims(PersistentVolumeClaim persistentVolumeClaim) throws VenusException {
        try {
            boolean f=k8sClient.persistentVolumeClaims().delete(persistentVolumeClaim);
            if(!f){
                throw new VenusException(VenusResponseStatus.K8S_EXCEPTION, "k8s异常,删除存储失败!");
            }
            return f;
        }catch (KubernetesClientException ex){
            logger.error(ex.getMessage(),ex);
            throw new VenusException(VenusResponseStatus.K8S_EXCEPTION, "k8s异常,删除存储失败!");
        }
    }

    @Override
    public Boolean createPersistentVolumeClaims(String pvcName,String namespace,String pvcAccessMode,String reqStorageSize) throws VenusException {
        try {
            Map<String,String> annotations = new HashMap<String,String>();
            annotations.put("volume.beta.kubernetes.io/storage-class",STORAGE_CLASS);
            String apiVersion="v1";
            String kind="PersistentVolumeClaim";
            ObjectMeta metadata=new ObjectMeta();
            metadata.setName(pvcName);
            metadata.setNamespace(namespace);
            metadata.setAnnotations(annotations);
            PersistentVolumeClaimSpec spec=new PersistentVolumeClaimSpec();
            List<String> accessMode=new ArrayList<String>();
            accessMode.add(pvcAccessMode);
            spec.setAccessModes(accessMode);
            ResourceRequirements resourceRequirements=new ResourceRequirements();
            Map<String,Quantity> requests=new HashMap<String,Quantity>();
            requests.put("storage",new Quantity(reqStorageSize));
            resourceRequirements.setRequests(requests);
            spec.setResources(resourceRequirements);
            PersistentVolumeClaim persistentVolumeClaim=new PersistentVolumeClaim(apiVersion,kind,metadata,spec,null);
            if(k8sClient.persistentVolumeClaims().create(persistentVolumeClaim)==null){
                throw new VenusException(VenusResponseStatus.K8S_EXCEPTION, "k8s异常,创建存储失败!");
            }
            return true;
        }catch (KubernetesClientException ex){
            logger.error(ex.getMessage(),ex);
            throw new VenusException(VenusResponseStatus.K8S_EXCEPTION, "k8s异常,创建存储失败!");
        }
    }
}